/*
 * File:    startup.c
 * Purpose: Generic Kinetis startup code
 *
 * Notes: modified by Hjhee for gramb at 20140125 11:38
 */

#include "common.h"

#if (defined(IAR))
	#pragma section=".data"
	#pragma section=".data_init"
	#pragma section=".bss"
	#pragma section="CodeRelocate"
	#pragma section="CodeRelocateRam"
#endif

/********************************************************************/
void common_startup(void){
    /* Declare a counter we'll use in all of the copy loops */
    uint32 n;

#ifndef KEIL
    /* Declare pointers for various data sections. These pointers
     * are initialized using values pulled in from the linker file
     */
    uint8 *data_ram,*data_rom,*data_rom_end;
    uint8 *bss_start,*bss_end;
#endif

#if (defined(IAR))
	/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
	extern uint32 __VECTOR_TABLE[104];
	extern uint32 __VECTOR_RAM[104];
#endif
	
    /* Copy the vector table to RAM */
    if(__VECTOR_RAM!=__VECTOR_TABLE){
        for(n=0; n<0x104; ++n)
            __VECTOR_RAM[n]=__VECTOR_TABLE[n];
    }
    /* Point the VTOR to the new copy of the vector table */
    write_vtor((uint32)__VECTOR_RAM);    
    
    /* Get the addresses for the .data section (initialized data section) */
#if (defined(IAR))
	data_ram=__section_begin(".data");
	data_rom=__section_begin(".data_init");
	data_rom_end=__section_end(".data_init");
	n=data_rom_end-data_rom;
#endif		

#ifndef __CC_ARM
	/* Copy initialized data from ROM to RAM */
	while(n--)
		*data_ram++=*data_rom++;
	
    /* Get the addresses for the .bss section (zero-initialized data) */
    #if (defined(IAR))
	bss_start=__section_begin(".bss");
	bss_end=__section_end(".bss");
    #endif

    /* Clear the zero-initialized data section */
    n=bss_end-bss_start;
    while(n--)
      *bss_start++=0;
#endif

    /* Get addresses for any code sections that need to be copied from ROM to RAM.
     * The IAR tools have a predefined keyword that can be used to mark individual
     * functions for execution from RAM. Add "__ramfunc" before the return type in
     * the function prototype for any routines you need to execute from RAM instead
     * of ROM. ex: __ramfunc void foo(void);
     */
#if (defined(IAR))
  	uint8* code_relocate_ram=__section_begin("CodeRelocateRam");
	uint8* code_relocate=__section_begin("CodeRelocate");
    uint8* code_relocate_end=__section_end("CodeRelocate");

    /* Copy functions from ROM to RAM */
    n=code_relocate_end-code_relocate;
    while(n--)
        *code_relocate_ram++=*code_relocate++;
#endif
}
/********************************************************************/
